iT邦幫忙

2024 iThome 鐵人賽

DAY 28
1

學習 Laravel 框架過程中很常可以看到所有的檔案都是 class,而且非常看重物件導向,其中依賴注入和繼承最常見;前端呢?今天來談談我所了解的 JavaScript 設計模式!

👍🏻👍🏻👍🏻 推薦好片:淺談 Javascript 設計模式 | Alex 宅幹嘛
回顧過去:第 16 天:建構子函數 - OOPs
參考文章:【翻譯】JavaScript 設計模式javascript设计模式【上】javascript设计模式【下】

設計模式


設計模式是經過驗證的解決方案,用於解決在軟體設計中常見的問題,另外也可以提高代碼的可讀性、可維護性和重用性。
JS design pattern

常見的設計模式


找到的文章中主要對模組模式、原型模式、代理模式、觀察者模式、工廠模式比較有感覺,回想起來似乎自己就有用到,所以對於這幾個設計模式說明。

模組模式 Module Pattern
模組模式用於封裝代碼,提供私有和公有接口,避免全局命名衝突。

const Module = (function () {
  // 私有變數 -> 在 module 外部不能被訪問,確保資料封裝
  let privateVar = "私人";

  return {
    // 可以存取斯有變數的功用函數
    publicMethod: function () {
      console.log(privateVar);
    },
    setPrivateVar: function (value) {
      privateVar = value;
    }
  };
})();

Module.publicMethod();  // "私人"
Module.setPrivateVar("New value");
Module.publicMethod();  // "New value"

原型模式 Prototype Pattern

回顧一下:第 15 天:JavaScript 的原型鏈與繼承第 16 天:建構子函數

原型模式基於原型鏈來創建對象,允許對象共享屬性和方法,從而節省內存。

function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function () {
  console.log(`Hello, my name is ${this.name}`);
};

const kuku = new Person("kuku");
const ting = new Person("ting");

kuku.sayHello(); // "Hello, my name is kuku"
ting.sayHello(); // "Hello, my name is ting"

代理模式 Proxy Pattern
代理模式提供了一個替代物件,通過該物件來控制對其他物件的訪問。

const RealSubject = {
  request: function () {
    console.log("Request processed");
  }
};

const Proxy = (function () {
  return {
    request: function () {
      console.log("Logging: Before request");
      RealSubject.request();
      console.log("Logging: After request");
    }
  };
})();

Proxy.request();

console.log

🔔 Proxy 代理是什麼!?
Proxy 物件允許在物件上的基本操作建立自訂行為,如屬性查找、賦值、枚舉 enum、函數呼叫等...

const target = {
  message1: "Hello",
  message2: "World"
};

const handler = {
  get: function (target, prop, receiver) {
    console.log(`Property '${prop}' was accessed.`);
    return Reflect.get(...arguments);
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.message1); // Logs: Property 'message1' was accessed. console.log(proxy.message2); // Logs: Property 'message2' was accessed.

觀察者模式
觀察者模式定義了一種一對多的依賴關係,使得當一個對象的狀態改變時,所有依賴於它的對象都會得到通知並自動更新。

function Subject() {
    this.observers = [];

    this.addObserver = function (observer) {
        this.observers.push(observer);
    };

    this.notifyObservers = function (data) {
        this.observers.forEach((observer) => observer.update(data));
    };
}

function Observer(name) {
    this.name = name;

    this.update = function (data) {
        console.log(`${this.name} received data: ${data}`);
    };
}

const subject = new Subject();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');

subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers('Hello, Observers!');
// 輸出:
// Observer 1 received data: Hello, Observers!
// Observer 2 received data: Hello, Observers!
class Subject {
    constructor() {
        this.observers = [];
    }

    addObserver(observer) {
        this.observers.push(observer);
    }

    notifyObservers() {
        this.observers.forEach(observer => observer.update());
    }
}

💡 這種模式就很像 Vue 的 VuexPinia,這類的狀態管理或事件處理,只要狀態改變,所有依賴的都會一起改變!

工廠模式

回顧一下:第 18 天:閉包與作用域

工廠模式是一種創建對象的模式,使用工廠方法來創建對象,而不是直接使用 new,這樣可以將對象的創建過程封裝起來,並提高代碼的可擴展性和可維護性。

function Car(make, model) {
    this.make = make;
    this.model = model;
}

function CarFactory() {
    this.createCar = function (make, model) {
        return new Car(make, model);
    };
}

const factory = new CarFactory();
const car1 = factory.createCar('Toyota', 'Corolla');
const car2 = factory.createCar('Honda', 'Civic');

console.log(car1); // Car { make: 'Toyota', model: 'Corolla' }
console.log(car2); // Car { make: 'Honda', model: 'Civic' }

上一篇
第 27 天:資料存儲與處理
下一篇
第 29 天:實戰項目 - 基礎項目 To_do List 構建
系列文
30天 JavaScript 提升計畫:從零到精通結合2024年的創新功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言